home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / doom / quake.zip / TRACER.ZIP / SRC / WEAPONS.QC
Text File  |  1996-08-09  |  27KB  |  1,290 lines

  1. /*
  2. */
  3. void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
  4. void () player_run;
  5. void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
  6. void(vector org, vector vel, float damage) SpawnBlood;
  7. void() SuperDamageSound;
  8.  
  9.  
  10. // called by worldspawn
  11. void() W_Precache =
  12. {
  13.     precache_sound ("weapons/r_exp3.wav");    // new rocket explosion
  14.     precache_sound ("weapons/rocket1i.wav");    // spike gun
  15.     precache_sound ("weapons/sgun1.wav");
  16.     precache_sound ("weapons/guncock.wav");    // player shotgun
  17.     precache_sound ("weapons/ric1.wav");    // ricochet (used in c code)
  18.     precache_sound ("weapons/ric2.wav");    // ricochet (used in c code)
  19.     precache_sound ("weapons/ric3.wav");    // ricochet (used in c code)
  20.     precache_sound ("weapons/spike2.wav");    // super spikes
  21.     precache_sound ("weapons/tink1.wav");    // spikes tink (used in c code)
  22.     precache_sound ("weapons/grenade.wav");    // grenade launcher
  23.     precache_sound ("weapons/bounce.wav");        // grenade bounce
  24.     precache_sound ("weapons/shotgn2.wav");    // super shotgun
  25.     precache_sound ("misc/talk.wav");    // super shotgun
  26.     precache_model ("progs/v_spike.mdl");    // super shotgun
  27. };
  28.  
  29. float() crandom =
  30. {
  31.     return 2*(random() - 0.5);
  32. };
  33.  
  34. /*
  35. ================
  36. W_FireAxe
  37. ================
  38. */
  39. void() W_FireAxe =
  40. {
  41.     local    vector    source;
  42.     local    vector    org;
  43.  
  44.     source = self.origin + '0 0 16';
  45.     traceline (source, source + v_forward*64, FALSE, self);
  46.     if (trace_fraction == 1.0)
  47.         return;
  48.     
  49.     org = trace_endpos - v_forward*4;
  50.  
  51.     if (trace_ent.takedamage)
  52.     {
  53.         trace_ent.axhitme = 1;
  54.         SpawnBlood (org, '0 0 0', 20);
  55.         T_Damage (trace_ent, self, self, 20);
  56.     }
  57.     else
  58.     {    // hit wall
  59.         sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  60.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  61.         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  62.         WriteCoord (MSG_BROADCAST, org_x);
  63.         WriteCoord (MSG_BROADCAST, org_y);
  64.         WriteCoord (MSG_BROADCAST, org_z);
  65.     }
  66. };
  67.  
  68.  
  69. //============================================================================
  70.  
  71.  
  72. vector() wall_velocity =
  73. {
  74.     local vector    vel;
  75.     
  76.     vel = normalize (self.velocity);
  77.     vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
  78.     vel = vel + 2*trace_plane_normal;
  79.     vel = vel * 200;
  80.     
  81.     return vel;
  82. };
  83.  
  84.  
  85. /*
  86. ================
  87. SpawnMeatSpray
  88. ================
  89. */
  90. void(vector org, vector vel) SpawnMeatSpray =
  91. {
  92.     local    entity missile, mpuff;
  93.     local    vector    org;
  94.  
  95.     missile = spawn ();
  96.     missile.owner = self;
  97.     missile.movetype = MOVETYPE_BOUNCE;
  98.     missile.solid = SOLID_NOT;
  99.  
  100.     makevectors (self.angles);
  101.  
  102.     missile.velocity = vel;
  103.     missile.velocity_z = missile.velocity_z + 250 + 50*random();
  104.  
  105.     missile.avelocity = '3000 1000 2000';
  106.     
  107. // set missile duration
  108.     missile.nextthink = time + 1;
  109.     missile.think = SUB_Remove;
  110.  
  111.     setmodel (missile, "progs/zom_gib.mdl");
  112.     setsize (missile, '0 0 0', '0 0 0');        
  113.     setorigin (missile, org);
  114. };
  115.  
  116. /*
  117. ================
  118. SpawnBlood
  119. ================
  120. */
  121. void(vector org, vector vel, float damage) SpawnBlood =
  122. {
  123.     particle (org, vel*0.1, 73, damage*2);
  124. };
  125.  
  126. /*
  127. ================
  128. spawn_touchblood
  129. ================
  130. */
  131. void(float damage) spawn_touchblood =
  132. {
  133.     local vector    vel;
  134.  
  135.     vel = wall_velocity () * 0.2;
  136.     SpawnBlood (self.origin + vel*0.01, vel, damage);
  137. };
  138.  
  139.  
  140. /*
  141. ================
  142. SpawnChunk
  143. ================
  144. */
  145. void(vector org, vector vel) SpawnChunk =
  146. {
  147.     particle (org, vel*0.02, 0, 10);
  148. };
  149.  
  150. /*
  151. ==============================================================================
  152.  
  153. MULTI-DAMAGE
  154.  
  155. Collects multiple small damages into a single damage
  156.  
  157. ==============================================================================
  158. */
  159.  
  160. entity    multi_ent;
  161. float    multi_damage;
  162.  
  163. void() ClearMultiDamage =
  164. {
  165.     multi_ent = world;
  166.     multi_damage = 0;
  167. };
  168.  
  169. void() ApplyMultiDamage =
  170. {
  171.     if (!multi_ent)
  172.         return;
  173.     T_Damage (multi_ent, self, self, multi_damage);
  174. };
  175.  
  176. void(entity hit, float damage) AddMultiDamage =
  177. {
  178.     if (!hit)
  179.         return;
  180.     
  181.     if (hit != multi_ent)
  182.     {
  183.         ApplyMultiDamage ();
  184.         multi_damage = damage;
  185.         multi_ent = hit;
  186.     }
  187.     else
  188.         multi_damage = multi_damage + damage;
  189. };
  190.  
  191. /*
  192. ==============================================================================
  193.  
  194. BULLETS
  195.  
  196. ==============================================================================
  197. */
  198.  
  199. /*
  200. ================
  201. TraceAttack
  202. ================
  203. */
  204. void(float damage, vector dir) TraceAttack =
  205. {
  206.     local    vector    vel, org;
  207.     
  208.     vel = normalize(dir + v_up*crandom() + v_right*crandom());
  209.     vel = vel + 2*trace_plane_normal;
  210.     vel = vel * 200;
  211.  
  212.     org = trace_endpos - dir*4;
  213.  
  214.     if (trace_ent.takedamage)
  215.     {
  216.         SpawnBlood (org, vel*0.2, damage);
  217.         AddMultiDamage (trace_ent, damage);
  218.     }
  219.     else
  220.     {
  221.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  222.         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  223.         WriteCoord (MSG_BROADCAST, org_x);
  224.         WriteCoord (MSG_BROADCAST, org_y);
  225.         WriteCoord (MSG_BROADCAST, org_z);
  226.     }
  227. };
  228.  
  229. /*
  230. ================
  231. FireBullets
  232.  
  233. Used by shotgun, super shotgun, and enemy soldier firing
  234. Go to the trouble of combining multiple pellets into a single damage call.
  235. ================
  236. */
  237. void(float shotcount, vector dir, vector spread) FireBullets =
  238. {
  239.     local    vector direction;
  240.     local    vector    src;
  241.     
  242.     makevectors(self.v_angle);
  243.  
  244.     src = self.origin + v_forward*10;
  245.     src_z = self.absmin_z + self.size_z * 0.7;
  246.  
  247.     ClearMultiDamage ();
  248.     while (shotcount > 0)
  249.     {
  250.         direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
  251.  
  252.         traceline (src, src + direction*2048, FALSE, self);
  253.         if (trace_fraction != 1.0)
  254.             TraceAttack (4, direction);
  255.  
  256.         shotcount = shotcount - 1;
  257.     }
  258.     ApplyMultiDamage ();
  259. };
  260.  
  261. /*
  262. ================
  263. W_FireShotgun
  264. ================
  265. */
  266. void() W_FireShotgun =
  267. {
  268.     local vector dir;
  269.  
  270.     sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);    
  271.  
  272.     self.punchangle_x = -2;
  273.     
  274.     self.currentammo = self.ammo_shells = self.ammo_shells - 1;
  275.     dir = aim (self, 100000);
  276.     FireBullets (6, dir, '0.04 0.04 0');
  277. };
  278.  
  279.  
  280. /*
  281. ================
  282. W_FireSuperShotgun
  283. ================
  284. */
  285. void() W_FireSuperShotgun =
  286. {
  287.     local vector dir;
  288.  
  289.     if (self.currentammo == 1)
  290.     {
  291.         W_FireShotgun ();
  292.         return;
  293.     }
  294.         
  295.     sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);    
  296.  
  297.     self.punchangle_x = -4;
  298.     
  299.     self.currentammo = self.ammo_shells = self.ammo_shells - 2;
  300.     dir = aim (self, 100000);
  301.     FireBullets (14, dir, '0.14 0.08 0');
  302. };
  303.  
  304.  
  305. /*
  306. ==============================================================================
  307.  
  308. ROCKETS
  309.  
  310. ==============================================================================
  311. */
  312.  
  313. void()    s_explode1    =    [0,        s_explode2] {};
  314. void()    s_explode2    =    [1,        s_explode3] {};
  315. void()    s_explode3    =    [2,        s_explode4] {};
  316. void()    s_explode4    =    [3,        s_explode5] {};
  317. void()    s_explode5    =    [4,        s_explode6] {};
  318. void()    s_explode6    =    [5,        SUB_Remove] {};
  319.  
  320. void() BecomeExplosion =
  321. {
  322.     self.movetype = MOVETYPE_NONE;
  323.     self.velocity = '0 0 0';
  324.     self.touch = SUB_Null;
  325.     setmodel (self, "progs/s_explod.spr");
  326.     self.solid = SOLID_NOT;
  327.     s_explode1 ();
  328. };
  329.  
  330. void() T_MissileTouch =
  331. {
  332.     local float    damg;
  333.  
  334.     if (other == self.owner)
  335.         return;        // don't explode on owner
  336.  
  337.     if (pointcontents(self.origin) == CONTENT_SKY)
  338.     {
  339.         remove(self);
  340.         return;
  341.     }
  342.  
  343.     damg = 100 + random()*20;
  344.     
  345.     if (other.health)
  346.     {
  347.         if (other.classname == "monster_shambler")
  348.             damg = damg * 0.5;    // mostly immune
  349.         T_Damage (other, self, self.owner, damg );
  350.     }
  351.  
  352.     // don't do radius damage to the other, because all the damage
  353.     // was done in the impact
  354.     T_RadiusDamage (self, self.owner, 120, other);
  355.  
  356. //    sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  357.     self.origin = self.origin - 8*normalize(self.velocity);
  358.  
  359.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  360.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  361.     WriteCoord (MSG_BROADCAST, self.origin_x);
  362.     WriteCoord (MSG_BROADCAST, self.origin_y);
  363.     WriteCoord (MSG_BROADCAST, self.origin_z);
  364.  
  365.     BecomeExplosion ();
  366. };
  367.  
  368.  
  369.  
  370. /*
  371. ================
  372. W_FireRocket
  373. ================
  374. */
  375. void() W_FireRocket =
  376. {
  377.     local    entity missile, mpuff;
  378.     
  379.     self.currentammo = self.am